package com.sundog.sundroid;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
import java.util.Scanner;

import org.jivesoftware.smack.ConnectionConfiguration;
import org.jivesoftware.smack.PacketListener;
import org.jivesoftware.smack.XMPPConnection;
import org.jivesoftware.smack.XMPPException;
import org.jivesoftware.smack.filter.PacketFilter;
import org.jivesoftware.smack.filter.PacketTypeFilter;
import org.jivesoftware.smack.packet.Message;
import org.jivesoftware.smack.packet.Packet;

import android.app.Activity;
import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.os.Bundle;
import android.os.Handler;
import android.util.Log;
import android.view.View;
import android.view.ViewGroup;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.TableLayout;
import android.widget.TableRow;
import android.widget.TextView;

import com.sundog.sundroid.google.GoogleService;

/**
 * This activity is displayed between voting rounds and displays voting status and results
 * 
 * @author Matt Smith
 *
 */
public class ModeratorResultsWaitingScreen extends Activity implements OnClickListener {
	
	/** Represents this class instance */
	private ModeratorResultsWaitingScreen screen = this;
	/** Represents this context */
	private Context context;
	/** User map */
	private static Map<String, String> users;
	/** User array */
	private static String [] userNames;
	/** Vote map */
	private Map<String, String> votes = new HashMap<String, String>();
	/** Spreadsheet ID */
	private static String id = "";
	/** On screen vote list */
	private ArrayList<TextView> voteList = new ArrayList<TextView>();
	/** Screen layout */
	private TableLayout tl;
	/** Individual vote view */
	private TextView child;
	/** Boolean to stop executing thread */
	private boolean execute = true;
	/** Array of votes */
	private static ArrayList<String> voteArray = new ArrayList<String>(0);
	/** Represents current view state */
	private Bundle state;
	/** Create a packet filter to receive messages of type Message */
	PacketFilter filter = new PacketTypeFilter(Message.class);
	
	/** Create a packet listener to process messages */
	PacketListener myListener = new PacketListener() {
		
		/** Process incoming messages */
		public void processPacket(Packet packet) {
			
			Message msg = (Message) packet;			
			voteHandler(msg);
       }};
    
    /**
     * Handles incoming messages
     * 
     * @param msg
     * 					the message to process
     */
    private void voteHandler(Message msg) {
    	
    	// Add vote to the vote array 
    	voteArray.add(msg.getBody());
    	Log.d("***", "Results Admin received message: " + msg.getBody() + " from " + msg.getFrom());
		
		// Create a scanner and parse the user name from the message 
		Scanner in = new Scanner(msg.getFrom());
		in.useDelimiter("/");
		String user = in.next();
		Log.d("USER", user);
		
		// Reply to user with moderators vote
		if(!screen.getIntent().getExtras().getString("moderator").equalsIgnoreCase(user)) {
			Message returnVote = new Message();
			returnVote.setTo(user);
			returnVote.setBody(votes.get(screen.getIntent().getExtras().getString("moderator")));
			connection.sendPacket(returnVote);
		}
				
		// Update the users vote
		votes.put(user, msg.getBody());
		
		// If all users have voted, update the vote list to display actual vote values
		if(!votes.containsValue("-1")) {			

			// Update vote list to contain actual vote values
			voteList = new ArrayList<TextView>();
			
			// Add votes to vote list
    		for(String s : votes.keySet()) {

    			Log.d("ITERATOR", "After Loop");
    			TextView tv = new TextView(context);
    			tv.setText(s + "......." + votes.get(s));
    			voteList.add(tv);
    		}
    		
    		// Add user votes to a new table layout
    		tl = new TableLayout(context);
    		for(TextView t : voteList) {
				tl.addView(t);
				Log.d("***", "Child added thrice");
			}			
    	} 
		
		// If some users still haven't voted, update the vote list to show who still needs to vote			
		else {
    		// Update what is going to be displayed on the screen
    		voteList = new ArrayList<TextView>();
    		for(String s : votes.keySet()) {
    			TextView tv = new TextView(context);
			
    			if(votes.get(s) == "-1") {
    				tv.setText(s + ".......###");
    				voteList.add(tv);
				
    			}else {
    				tv.setText(s + ".......Voted");
    				voteList.add(tv);
    			}
    		}
		
    		// Add updated vote list to a new table layout
    		tl = new TableLayout(context);
    		for(TextView t : voteList) {
    			tl.addView(t);
    			Log.d("***", "Child added 3");
    		}
		}
		
		// Update UI to reflect changes
		mHandler.post(mUpdateResults);
    }
	
	/** Connection configuration for XMPP messaging */
	private final ConnectionConfiguration connConfig = new ConnectionConfiguration("talk.google.com", 80, "jabber.org"); 
	/** Establishes XMPP connection using the connection configuration */
	private final XMPPConnection connection = new XMPPConnection(connConfig);
	
	/** Thread to listen for messages */
	private final Thread t = new Thread() {
		
        public void run() {
    		// Continue execution until voting round is over
        	while(execute) {
        		try {
        			
                	Thread.sleep(5000);
                }
                catch(InterruptedException e) {
                	Log.d("ERROR", "Thread exception" + e.getMessage());
                }
        	}
        	Log.d("checking", "Thread 111" );
        }
    };
	
    // Handler for call backs to the UI thread 
    final Handler mHandler = new Handler(); 

    // Create runnable for posting UI updates 
    final Runnable mUpdateResults = new Runnable() { 
        public void run() { 
        	updateResultsInUi(); 
        }}; 
    
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		
		super.onCreate(savedInstanceState);
		setContentView(R.layout.moderatorresultswaitingscreen);
		
		// Initialize variables and user list
		tl = new TableLayout(this.getApplicationContext());
		child = new TextView(this.getApplicationContext());
		context = this.getApplicationContext();
		state = savedInstanceState;
		initializeUserList();
		
		// Connect to server and send a mock vote to the vote handler
		connectToServer();
    	Message msg = new Message();
		msg.setFrom("demosundog@gmail.com/");
		msg.setBody("8");
		voteHandler(msg);
		
		// Set up click listeners
		View ResolveButton = this.findViewById(R.id.resolve_button);
		ResolveButton.setOnClickListener(this);
		View RevoteButton = this.findViewById(R.id.revote_button);
		RevoteButton.setOnClickListener(this);
		
		t.start();
	}
	
	/**
	 * Process button clicks
	 */
	public void onClick(View v) {
		
		switch (v.getId()) {
    		case R.id.resolve_button:
    			//screen.finish();
    			execute = false;
    			Intent i = new Intent(this, Resolve.class);
        		startActivity(i);
        		connection.disconnect();
        		break;
        		
    		case R.id.revote_button:
    			execute = false;
    			
    			Message msg = new Message();
        		msg.setBody("Revote");

        		for(String s : votes.keySet()) {
        			
        	    	if(s.equalsIgnoreCase(screen.getIntent().getExtras().getString("moderator"))) {
        	    		this.onDestroy();
        	    	} else {
        	    		msg.setTo(s);
            			connection.sendPacket(msg);
        	    	}
        		}
        	break;
		}
	}
	
	@Override
	public void onDestroy() {
		
		this.startActivity(this.getIntent());
		super.onDestroy();
	}
	
	/**
	 * Refresh the screen after a change to it has been made
	 */
	private void updateResultsInUi() {
		
		this.setContentView(R.layout.moderatorresultswaitingscreen);
		this.addContentView(tl, new TableRow.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT));
		
		View ResolveButton = this.findViewById(R.id.resolve_button);
		ResolveButton.setOnClickListener(this);
		View RevoteButton = this.findViewById(R.id.revote_button);
		RevoteButton.setOnClickListener(this);
	}
	
	/**
	 * Initialize initial user list state
	 */
	private void initializeUserList() {
		// Retrieve spreadsheet ID
		id = this.getIntent().getStringExtra("SID");
		
		// Retrieve the list of users from the spreadsheet
		users = GoogleService.returnUserList(id);
		userNames = users.keySet().toArray(new String[users.size()]);

		// Set initial votes to -1
		for(String s : userNames) {
			
			TextView child2 = new TextView(this.getApplicationContext());
			votes.put(s, "-1");
			child2.setText(s + ".......###");
			voteList.add(child2);
		}
		
		// Add each vote to the vote list
		for(TextView t : voteList) {
			tl.addView(t);
			Log.d("***", "Child added");
		}

		// Add the vote list to the screen
		this.addContentView(tl, new TableRow.LayoutParams(ViewGroup.LayoutParams.FILL_PARENT, ViewGroup.LayoutParams.FILL_PARENT));
	}
	
	/**
	 * Set up a connection to the Jabber server
	 */
	private void connectToServer() {
		try {	
			// Connect to the server if not already connected and log in with user name and password from previous activity
			if(!connection.isConnected()) {
				Log.d("***", "Admin Connect results...");
				connection.connect();
				connection.login("demosundog@gmail.com", "sundog101");
				Log.d("***", "Admin Connected results");
			}
		} catch (XMPPException e) {
			Log.d("***", "XMPPException" + e.getMessage());
		}
		
		// Add a packet listener to the connection. The parameters were created above
		connection.addPacketListener(myListener, filter);
	}
}
